﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ApplicationLibrary;
using ApplicationLibrary.SqlConnector;
using Plumber.Accounting.ModuleData;
using Plumber.Masters.ModuleData;
using Plumber.Sales.ModuleData;

namespace Plumber.Accounting.Forms
{
    public partial class EmittedDocJournalEntries : WeifenLuo.WinFormsUI.Docking.DockContent
    {
        private DRMasterTypeByType dRMasterTypeByType;
        private DRMasters dRMaster;
        private DRMasterType dRMasterType;
        private DRJournalEntryTotalByType dRJETotal;
        private DRSalesInvoices drSalesInvoice;
        private string adminType;
        private string condomType;
        private bool adding = true;

        public ListView.ListViewItemCollection List { get { return lsvInvoice.Items; } }

        public string MasterType { get { return cbbType.GetValue<string>(); } }

        public string FromType { get { return cbbFromType.GetValue<string>(); } }

        public string FromCode { get { return rdrFromCode.Text; } }

        public double Total { get { return ntbTotal.Double; } }

        public List<string> ListDocumentNo = new List<string>();

        public EmittedDocJournalEntries()
        {
            InitializeComponent();
            InitializeAuxComponent();
        }

        private void InitializeAuxComponent()
        {
            dRMaster = new DRMasters(false);
            dRMasterType = new DRMasterType(DRMasterType.Module.All);
            dRJETotal = new DRJournalEntryTotalByType();
            drSalesInvoice = new DRSalesInvoices(false);
            dRMasterTypeByType = new DRMasterTypeByType();
            if (dRMasterTypeByType.Find(MasterTypes.E_Condominium))
                condomType = dRMasterTypeByType.GetValue<string>(PL_MasterType.Code, 0);

            if (dRMasterTypeByType.Find(MasterTypes.E_Administrator))
            {
                adminType = dRMasterTypeByType.GetValue<string>(PL_MasterType.Code, 0);
                rdrAdmin.AttachCodeType(adminType);
                rdrAdmin.RadarForm = new RadarMasterForm(adminType, RadarMasterForm.Module.Master);
                rdrAdmin.RadarForm.EnableAddOnFly = false;
                rdrAdmin.DescriptionControl = lblDescAdmin;
            }

            rdrMaster.RadarForm = new RadarMasterForm(RadarMasterForm.Module.All);
            rdrMaster.RadarForm.EnableAddOnFly = false;
            rdrMaster.DescriptionControl = lblDescMaster;

            rdrFromCode.RadarForm = new RadarMasterForm(RadarMasterForm.Module.All);
            rdrFromCode.RadarForm.EnableAddOnFly = false;
            rdrFromCode.DescriptionControl = lblDescFrom;

            cbbType.AttachDataReader(new RRMasterTypeForInvoice());
            cbbType_SelectedValueChanged(this, EventArgs.Empty);

            cbbFromType.AttachDataReader(new RRMasterTypeByType(MasterTypes.E_BankCash));
            cbbFromType_SelectedValueChanged(this, EventArgs.Empty);

            ntbTotal.Prefix = Properties.Resources.CurrencySimbol;
        }

        private void cbbType_SelectedValueChanged(object sender, EventArgs e)
        {
            rdrAdmin.Enabled = cbbType.GetValue<string>() == condomType;
            if (!rdrAdmin.Enabled)
                rdrAdmin.Text = string.Empty;

            dRMasterType.Find(cbbType.GetValue<string>());
            rdrMaster.Enabled = dRMasterType.GetValue<CodeMode>(PL_MasterType.CodeMode) != CodeMode.E_IsEmpty;
            if (!rdrMaster.Enabled)
                rdrMaster.ResetText();
            else
            {
                rdrMaster.AttachCodeType(cbbType.GetValue<string>());
                rdrMaster.RadarForm.FilterType = cbbType.GetValue<string>();
            }
            lblDescMaster.Text = string.Empty;
            lblDescAdmin.Text = string.Empty;
        }

        private void cbbFromType_SelectedValueChanged(object sender, EventArgs e)
        {
            dRMasterType.Find(cbbFromType.GetValue<string>());
            rdrFromCode.Enabled = dRMasterType.GetValue<CodeMode>(PL_MasterType.CodeMode) != CodeMode.E_IsEmpty;
            if (!rdrFromCode.Enabled)
                rdrFromCode.Text = string.Empty;
            else
            {
                rdrFromCode.AttachCodeType(cbbFromType.GetValue<string>());
                rdrFromCode.RadarForm.FilterType = cbbFromType.GetValue<string>();
            }
            lblDescFrom.Text = string.Empty;
        }

        private void btnLoad_Click(object sender, EventArgs e)
        {
            ntbTotal.Double = 0;
            LoadData();
        }

        private void LoadData()
        {
            lsvInvoice.Items.Clear();

            QueryBuilder qb = new QueryBuilder();
            qb.SetQualified = true;
            using (SqlABCommand scc = new SqlABCommand(GlobalInfo.LoginInfo.ProviderType))
            {
                scc.Connection = GlobalInfo.SqlConnection;

                qb.AddSelectAll(PL_JournalEntryDetail.Name);
                qb.AddSelect(PL_JournalEntry.PostingDate);
                qb.AddSelect(PL_JournalEntry.InvoiceType);
                qb.AddFrom(PL_JournalEntryDetail.Name);
                qb.AddJoin(QueryBuilder.JoinType.OUTER_LEFT, PL_JournalEntry.JournalNo, PL_JournalEntryDetail.JournalNo);

                qb.AddJoin(QueryBuilder.JoinType.OUTER_LEFT, PL_SalesInvoices.Type, PL_JournalEntryDetail.Type);
                qb.AddColumnJoinAnd(PL_SalesInvoices.Master, PL_JournalEntryDetail.Code);
                qb.AddColumnJoinAnd(PL_SalesInvoices.InvoiceNo, PL_JournalEntryDetail.DocumentNo);

                qb.AddCompare<string>(PL_JournalEntryDetail.Type, cbbType.GetValue<string>());
                qb.AddCompare<bool>(PL_JournalEntryDetail.Close, false);
                qb.AddCompare<double>(PL_JournalEntryDetail.From, 0);
                qb.AddCompare<double>(PL_JournalEntryDetail.To, 0, "!=");
                qb.AddCompareIN<int>(PL_JournalEntry.InvoiceType, "{0},{1}", InvoiceType.E_InvoiceEm.Int(), InvoiceType.E_DebitNoteEm.Int());

                if (!rdrMaster.IsEmpty)
                {
                    SqlABParameter p1 = new SqlABParameter("@p1", PL_JournalEntryDetail.Code);
                    qb.AddCompare(PL_JournalEntryDetail.Code, p1);
                    scc.Parameters.Add(p1);
                    p1.Value = rdrMaster.Text;
                }

                if (cbbType.GetValue<string>() == condomType && !String.IsNullOrEmpty(rdrAdmin.Text))
                {
                    SqlABParameter p2 = new SqlABParameter("@p2", PL_Masters.Administrator);
                    qb.AddCompare(PL_SalesInvoices.Administrator, p2);
                    scc.Parameters.Add(p2);
                    p2.Value = rdrAdmin.Text;
                }

                qb.AddOrder(PL_JournalEntry.PostingDate);
                qb.AddOrder(PL_JournalEntryDetail.DocumentNo);

                scc.CommandText = qb.Query;

                SqlABDataReader dr = scc.ExecuteReader();
                try
                {
                    adding = true;
                    while (dr.Read())
                    {
                        AddRow(dr);
                    }
                    dr.Close();

                    foreach (ColumnHeader col in lsvInvoice.Columns)
                        col.Width = -1;
                    adding = false;
                }
                catch (Exception e)
                {
                    if (ApplicationLibrary.Emailer.EmailSender.SendException)
                    {
                        ApplicationLibrary.Emailer.EmailSender.ToAddress = "mauro.rogledi@gmail.com";
                        ApplicationLibrary.Emailer.EmailSender.SendMail(e.Message, e.StackTrace, "");
                    }
                }
                finally
                {
                }
            }
        }

        private void AddRow(SqlABDataReader dr)
        {
            if (ListDocumentNo.Contains(dr.GetValue<string>(PL_JournalEntryDetail.DocumentNo)))
                return;

            dRJETotal.Find(dr.GetValue<string>(PL_JournalEntryDetail.DocumentNo),
                            dr.GetValue<string>(PL_JournalEntryDetail.Type),
                            dr.GetValue<string>(PL_JournalEntryDetail.Code));

            double total = dr.GetValue<double>(PL_JournalEntryDetail.To);
            double partial = dRJETotal.GetValue<double>(PL_JournalEntryDetail.From);
            if (total == partial)
                return;

            drSalesInvoice.Find(global::InvoiceType.E_InvoiceEm, dr.GetValue<string>(PL_JournalEntryDetail.DocumentNo));
            ListViewItemPayment lvi = new ListViewItemPayment(total, partial, drSalesInvoice.GetValue<bool>(PL_SalesInvoices.BankRestraint));
            
            lvi.SubItems.Add(dr.GetFormatValue<InvoiceType>(PL_JournalEntry.InvoiceType)).Name = PL_JournalEntry.InvoiceType.Name;
            lvi.SubItems.Add(dr.GetValue<string>(PL_JournalEntryDetail.DocumentNo)).Name = PL_JournalEntryDetail.DocumentNo.Name;
            lvi.SubItems.Add(dr.GetFormatValue<DateTime>(PL_JournalEntry.PostingDate)).Name = PL_JournalEntry.PostingDate.Name;
            lvi.SubItems.Add(dr.GetFormatValue<string>(PL_JournalEntryDetail.Code)).Name = PL_JournalEntryDetail.Code.Name;

            if (dRMaster.Find(dr.GetValue<string>(PL_JournalEntryDetail.Type), dr.GetValue<string>(PL_JournalEntryDetail.Code)))
                lvi.SubItems.Add(dRMaster.GetValue<string>(PL_Masters.Description)).Name = PL_Masters.Description.Name;
            else
                lvi.SubItems.Add("???").Name = PL_Masters.Description.Name;

            lvi.SubItems.Add(FormatData.GetFormatData<double>(total)).Name = "Total";



            lvi.SubItems.Add(FormatData.GetFormatData<double>(total - partial)).Name = "Partial";
            lvi.SubItems.RemoveAt(0);

            lsvInvoice.Items.Add(lvi);
        }

        private void lsvInvoice_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            if (adding)
                return;
            ListViewItemPayment lvi = e.Item as ListViewItemPayment;

            Double val = lvi.Total - lvi.Partial;
            ntbTotal.Double += e.Item.Checked ? val : -val;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }

    internal class ListViewItemPayment : ListViewItem
    {
        public double Total { get; set; }
        public double Partial { get; set; }
        public bool HasBankRestraint { get; set; }
        public ListViewItemPayment(double total, double partial, bool hasBankRestraint)
        {
            Total = total;
            Partial = partial;
            HasBankRestraint = hasBankRestraint;
        }
    }
}